package com.dsteiner.xelavos.client.controller;

import static com.dsteiner.xelavos.client.controller.IHistoryToken.*;

import java.util.HashMap;
import java.util.Map;

import com.dsteiner.widgets.client.domain.ModelObject;
import com.dsteiner.widgets.client.event.EventListener;
import com.dsteiner.widgets.client.event.EventManager;
import com.dsteiner.widgets.client.event.EventManagerImpl;
import com.dsteiner.xelavos.client.event.GetObjectEvent;
import com.dsteiner.xelavos.client.event.SendMessageEvent;
import com.dsteiner.xelavos.client.event.TabSelectionEvent;
import com.dsteiner.xelavos.client.model.MainTabModel;
import com.dsteiner.xelavos.client.model.SearchModel;
import com.dsteiner.xelavos.client.model.MainTabModel.Tab;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.History;

public class PlaceController {

	private static final String TOKEN_SEPARATOR = "~";
	private static final String VALUE_SEPARATOR = ":";
	public static final String SUB_VALUE_SEPARATOR = ";";

	private interface HistoryCommand {
		void execute(String value);
	}
	
	private static Map<String, HistoryCommand> historyCommands = new HashMap<String, HistoryCommand>();
	private static EventManager eventManager = EventManagerImpl.getInstance();
	
	static{
		historyCommands.put(SELECTED_TAB, new HistoryCommand(){
			public void execute(String value) {
				Tab tab = MainTabModel.getTab(Integer.parseInt(value));
				eventManager.fireEvent(new TabSelectionEvent(tab, true));
			}
		});
		historyCommands.put(OBJECT_ID, new HistoryCommand(){
			public void execute(String value) {
				eventManager.fireEvent(new GetObjectEvent(value));
			}
		});
		historyCommands.put(SHOW_MESSAGE_BOX, new HistoryCommand(){
			public void execute(String value) {
				HT_SHOW_MESSAGE_BOX.parse(value);
				eventManager.fireEvent(new SendMessageEvent(HT_SHOW_MESSAGE_BOX.getValue().getId(), 
						HT_SHOW_MESSAGE_BOX.getValue().getFirstName()));
			}
		});
	}
	
	public PlaceController() {
		History.addValueChangeHandler(new ValueChangeHandler<String>(){
			public void onValueChange(ValueChangeEvent<String> event) {
				String value = event.getValue();
				historyChanged(value);
			}
		});
	}
	
	public static void setEventManager(EventManager eventManager) {
		PlaceController.eventManager = eventManager;
	}
	
	private void addHistoryToken(int tabId) {
		String token = getHistoryToken(HT_SELECTED_TAB.setValue(tabId));
		System.out.println("PlaceController.addHistoryToken() "+token);
		History.newItem(token, false);
	}

	public void registerEventManager(EventManager eventManager) {
		eventManager.registerListener(TabSelectionEvent.class, new EventListener<TabSelectionEvent>(){
			public void onEvent(TabSelectionEvent event) {
				if(!event.isProgrammatically())
					addHistoryToken(event.getTab().getId());
			}
		});
	}

	protected static void historyChanged(String value) {
		System.out.println("History.onValueChange() :"+value);
		String[] tokens = value.split(TOKEN_SEPARATOR);
		for (int i = 0; i < tokens.length; i++) {
			String token = tokens[i];
			String[] nameAndValue = token.split(VALUE_SEPARATOR);
			HistoryCommand historyCommand = historyCommands.get(nameAndValue[0]);
			if(historyCommand != null)
				historyCommand.execute(nameAndValue[1]);
		}
	}

	public static String getHistoryToken(IHistoryToken... historyItems) {
		StringBuffer sb = new StringBuffer();
		for (IHistoryToken historyItem : historyItems) {
			sb.append(historyItem.getName()).append(VALUE_SEPARATOR).append(historyItem.getValueAsString());
			if(historyItems[historyItems.length-1] != historyItem)
				sb.append(TOKEN_SEPARATOR);
		}
		return sb.toString();
	}
}
